package com.ning.parking.domain;


import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import cn.hutool.core.date.BetweenFormatter;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.ning.parking.domain.VO.BillingResult;
import com.ning.parking.domain.dto.ParkingDTO;
import com.scsonic.common.domain.enter.CarInfoDTO;
import com.scsonic.common.domain.enter.CarTypeInfoVO;
import com.scsonic.common.domain.payment.pay.PayOrderDTO;
import com.scsonic.common.enums.StatusEnum;
import com.scsonic.common.enums.parking.*;
import com.scsonic.common.enums.parklot.DrivewayTypeEnum;
import com.scsonic.common.enums.trade.PayStatusEnum;
import com.scsonic.common.enums.trade.TradePlatformEnum;
import lombok.Data;

/**
 * 停车记录表
 * @TableName parking_record
 */
@TableName(value ="parking_record")
public class ParkingRecord implements Serializable {
    /**
     * 主键
     */
    @TableId(value = "record_id", type = IdType.AUTO)
    private Long recordId;

    /**
     * 车场id
     */
    private Long parkingLotId;

    /**
     * 车场名称
     */
    private String parkingLotName;

    /**
     * 主车场id
     */
    private Long parentParkingLotId;

    /**
     * 主车场名称
     */
    private String parentParkingLotName;

    /**
     * 通道id
     */
    private Long entDrivewayId;

    /**
     * 通道名称
     */
    private String entDrivewayName;

    /**
     * 入场车辆照片
     */
    private String entCarImageUrl;

    /**
     * 入场车牌照片
     */
    private String entLicenseImageUrl;

    /**
     * 入场时间
     */
    @JSONField(format = DatePattern.NORM_DATETIME_PATTERN)
    private Date entTime;

    /**
     * 车牌号码
     */
    private String carLicense;

    /**
     * 车牌颜色（0：未知，1：蓝牌，2：黄牌，3：白牌，4：黑牌，5：绿牌）
     */
    private LicenseColorEnum licenseColor;

    /**
     * 车牌置信度
     */
    private Integer credibleLevel;

    /**
     * 车牌是否修正（0：否，1：是）
     */
    private StatusEnum licenseRevise;

    /**
     * 车型（0：小型车，1：中型车，2：大型车）
     */
    private CarTypeEnum carType;

    /**
     * 无牌车身份唯一标识，微信openid或通道卡码
     */
    private String noneLicenseIdentify;

    /**
     * 停车状态（1：在场，5：已离场 ）
     */
    private ParkingStatusEnum parkingStatus;

    /**
     * 停车类型(1：白名单，2：月租，3：临停)
     */
    private ParkingTypeEnum parkingType;

    /**
     * 停车车辆类型（0：普通临停，1：白名单车辆，2：黑名单车辆，3：包月车辆，4：特殊临停，5：专区车辆）
     */
    private ParkingCarTypeEnum parkingCarType;

    /**
     * 停车车辆类型id
     */
    private Long carTypeId;

    /**
     * 停车车辆类型名称
     */
    private String carTypeName;

    /**
     * 车位号
     */
    private String spaceNumber;

    /**
     * 车位照片图
     */
    private String spaceImageUrl;

    /**
     * 是否子场停车记录（0：主场停车记录，1：子场停车记录）
     */
    private StatusEnum subParkingFlag;

    /**
     * 子场记录时，主场停车记录id
     */
    private Long parentRecordId;

    /**
     * 通道id
     */
    private Long exitDrivewayId;

    /**
     * 通道名称
     */
    private String exitDrivewayName;

    /**
     * 出口车辆照片
     */
    private String exitCarImageUrl;

    /**
     * 出口车牌照片
     */
    private String exitLicenseImageUrl;

    /**
     * 出口时间
     */
    @JSONField(format = DatePattern.NORM_DATETIME_PATTERN)
    private Date exitTime;

    /**
     * 计费截止时间
     */
    private Date chargeEndTime;

    /**
     * 停车时长分钟
     */
    private String parkingTime;

    /**
     * 免费时长（分）
     */
    private Integer freeTime;

    /**
     * 停车金额
     */
    private BigDecimal amount;

    /**
     * 折扣金额（元）
     */
    private BigDecimal discountAmount;

    /**
     * 应付金额（元）
     */
    private BigDecimal payableAmount;

    /**
     * 支付金额（元）
     */
    private BigDecimal payAmount;

    /**
     * 支付订单号
     */
    private String payOrderNo;

    /**
     * 下单时间
     */
    private Date orderTime;

    /**
     * 支付状态（0：无需支付，1：待支付，2：已支付，3：支付失败）
     */
    private PayStatusEnum payStatus;

    /**
     * 支付时间
     */
    @JSONField(format = DatePattern.NORM_DATETIME_PATTERN)
    private Date payTime;


    @TableField(exist = false)
    private String recordIdStr;

    /**
     * 支付场景：1-通道支付, 2-无感支付,3-场内支付,4-自助缴费机,5-小程序支付,6-岗亭收费
     */
    private PaySceneEnum payScene;

    /**
     * 支付渠道：1-微信,2-支付宝,3-商户抵扣,4-现金,5-银行卡
     */
    private TradePlatformEnum payChannel;

    /**
     * 收款人姓名
     */
    private String payeeName;

    /**
     * 收款人员工号
     */
    private String payeeEmployeeNo;

    /**
     * 收款人id
     */
    private Long payeeId;

    /**
     * 离场类型（1：出口抓拍（正常），2：人工放行，3：入场自动结束未离场的订单，4：抄牌小助手清理）
     */
    private ExitingTypeEnum exitingType;

    /**
     * 备注
     */
    private String remark;

    /**
     * 数据同步时间
     */
    private Long syncDataTime;

    /**
     * 创建人
     */
    private String createBy;

    /**
     * 创建时间
     */
    @JSONField(format = DatePattern.NORM_DATETIME_PATTERN)
    private Date createTime;

    /**
     * 更新人
     */
    private String updateBy;

    /**
     * 更新时间
     */
    @JSONField(format = DatePattern.NORM_DATETIME_PATTERN)
    private Date updateTime;

    /**
     * 删除标记
     */
    private Byte delFlag;

    @TableField(exist = false)
    private List<ParkingPayOrder> parkingPayOrders;

    @TableField(exist = false)
    private String ledShow;

    @TableField(exist = false)
    private static final long serialVersionUID = 1L;

    public Long getRecordId() {
        return recordId;
    }

    public void setRecordId(Long recordId) {
        this.recordId = recordId;
        this.recordIdStr = recordId.toString();
    }

    public Long getParkingLotId() {
        return parkingLotId;
    }

    public void setParkingLotId(Long parkingLotId) {
        this.parkingLotId = parkingLotId;
    }

    public String getParkingLotName() {
        return parkingLotName;
    }

    public void setParkingLotName(String parkingLotName) {
        this.parkingLotName = parkingLotName;
    }

    public Long getParentParkingLotId() {
        return parentParkingLotId;
    }

    public void setParentParkingLotId(Long parentParkingLotId) {
        this.parentParkingLotId = parentParkingLotId;
    }

    public String getParentParkingLotName() {
        return parentParkingLotName;
    }

    public void setParentParkingLotName(String parentParkingLotName) {
        this.parentParkingLotName = parentParkingLotName;
    }

    public Long getEntDrivewayId() {
        return entDrivewayId;
    }

    public void setEntDrivewayId(Long entDrivewayId) {
        this.entDrivewayId = entDrivewayId;
    }

    public String getEntDrivewayName() {
        return entDrivewayName;
    }

    public void setEntDrivewayName(String entDrivewayName) {
        this.entDrivewayName = entDrivewayName;
    }

    public String getEntCarImageUrl() {
        return entCarImageUrl;
    }

    public void setEntCarImageUrl(String entCarImageUrl) {
        this.entCarImageUrl = entCarImageUrl;
    }

    public String getEntLicenseImageUrl() {
        return entLicenseImageUrl;
    }

    public void setEntLicenseImageUrl(String entLicenseImageUrl) {
        this.entLicenseImageUrl = entLicenseImageUrl;
    }

    public Date getEntTime() {
        return entTime;
    }

    public void setEntTime(Date entTime) {
        this.entTime = entTime;
    }

    public String getCarLicense() {
        return carLicense;
    }

    public void setCarLicense(String carLicense) {
        this.carLicense = carLicense;
    }

    public LicenseColorEnum getLicenseColor() {
        return licenseColor;
    }

    public void setLicenseColor(LicenseColorEnum licenseColor) {
        this.licenseColor = licenseColor;
    }

    public Integer getCredibleLevel() {
        return credibleLevel;
    }

    public void setCredibleLevel(Integer credibleLevel) {
        this.credibleLevel = credibleLevel;
    }

    public StatusEnum getLicenseRevise() {
        return licenseRevise;
    }

    public void setLicenseRevise(StatusEnum licenseRevise) {
        this.licenseRevise = licenseRevise;
    }

    public CarTypeEnum getCarType() {
        return carType;
    }

    public void setCarType(CarTypeEnum carType) {
        this.carType = carType;
    }

    public String getNoneLicenseIdentify() {
        return noneLicenseIdentify;
    }

    public void setNoneLicenseIdentify(String noneLicenseIdentify) {
        this.noneLicenseIdentify = noneLicenseIdentify;
    }

    public ParkingStatusEnum getParkingStatus() {
        return parkingStatus;
    }

    public void setParkingStatus(ParkingStatusEnum parkingStatus) {
        this.parkingStatus = parkingStatus;
    }

    public ParkingTypeEnum getParkingType() {
        return parkingType;
    }

    public void setParkingType(ParkingTypeEnum parkingType) {
        this.parkingType = parkingType;
    }

    public ParkingCarTypeEnum getParkingCarType() {
        return parkingCarType;
    }

    public void setParkingCarType(ParkingCarTypeEnum parkingCarType) {
        this.parkingCarType = parkingCarType;
    }

    public Long getCarTypeId() {
        return carTypeId;
    }

    public void setCarTypeId(Long carTypeId) {
        this.carTypeId = carTypeId;
    }

    public String getCarTypeName() {
        return carTypeName;
    }

    public void setCarTypeName(String carTypeName) {
        this.carTypeName = carTypeName;
    }

    public String getSpaceNumber() {
        return spaceNumber;
    }

    public void setSpaceNumber(String spaceNumber) {
        this.spaceNumber = spaceNumber;
    }

    public String getSpaceImageUrl() {
        return spaceImageUrl;
    }

    public void setSpaceImageUrl(String spaceImageUrl) {
        this.spaceImageUrl = spaceImageUrl;
    }

    public StatusEnum getSubParkingFlag() {
        return subParkingFlag;
    }

    public void setSubParkingFlag(StatusEnum subParkingFlag) {
        this.subParkingFlag = subParkingFlag;
    }

    public Long getParentRecordId() {
        return parentRecordId;
    }

    public void setParentRecordId(Long parentRecordId) {
        this.parentRecordId = parentRecordId;
    }

    public Long getExitDrivewayId() {
        return exitDrivewayId;
    }

    public void setExitDrivewayId(Long exitDrivewayId) {
        this.exitDrivewayId = exitDrivewayId;
    }

    public String getExitDrivewayName() {
        return exitDrivewayName;
    }

    public void setExitDrivewayName(String exitDrivewayName) {
        this.exitDrivewayName = exitDrivewayName;
    }

    public String getExitCarImageUrl() {
        return exitCarImageUrl;
    }

    public void setExitCarImageUrl(String exitCarImageUrl) {
        this.exitCarImageUrl = exitCarImageUrl;
    }

    public String getExitLicenseImageUrl() {
        return exitLicenseImageUrl;
    }

    public void setExitLicenseImageUrl(String exitLicenseImageUrl) {
        this.exitLicenseImageUrl = exitLicenseImageUrl;
    }

    public Date getExitTime() {
        return exitTime;
    }

    public void setExitTime(Date exitTime) {
        this.exitTime = exitTime;
    }

    public Date getChargeEndTime() {
        return chargeEndTime;
    }

    public void setChargeEndTime(Date chargeEndTime) {
        this.chargeEndTime = chargeEndTime;
    }

    public String getParkingTime() {
        return parkingTime;
    }

    public void setParkingTime(String parkingTime) {
        this.parkingTime = parkingTime;
    }

    public Integer getFreeTime() {
        return freeTime;
    }

    public void setFreeTime(Integer freeTime) {
        this.freeTime = freeTime;
    }

    public BigDecimal getAmount() {
        return amount;
    }

    public void setAmount(BigDecimal amount) {
        this.amount = amount;
    }

    public BigDecimal getDiscountAmount() {
        return discountAmount;
    }

    public void setDiscountAmount(BigDecimal discountAmount) {
        this.discountAmount = discountAmount;
    }

    public BigDecimal getPayableAmount() {
        return payableAmount;
    }

    public void setPayableAmount(BigDecimal payableAmount) {
        this.payableAmount = payableAmount;
    }

    public BigDecimal getPayAmount() {
        return payAmount;
    }

    public void setPayAmount(BigDecimal payAmount) {
        this.payAmount = payAmount;
    }

    public String getPayOrderNo() {
        return payOrderNo;
    }

    public void setPayOrderNo(String payOrderNo) {
        this.payOrderNo = payOrderNo;
    }

    public Date getOrderTime() {
        return orderTime;
    }

    public void setOrderTime(Date orderTime) {
        this.orderTime = orderTime;
    }

    public PayStatusEnum getPayStatus() {
        return payStatus;
    }

    public void setPayStatus(PayStatusEnum payStatus) {
        this.payStatus = payStatus;
    }

    public Date getPayTime() {
        return payTime;
    }

    public void setPayTime(Date payTime) {
        this.payTime = payTime;
    }

    public String getRecordIdStr() {
        return recordIdStr;
    }

    public void setRecordIdStr(String recordIdStr) {
        this.recordIdStr = recordIdStr;
    }

    public PaySceneEnum getPayScene() {
        return payScene;
    }

    public void setPayScene(PaySceneEnum payScene) {
        this.payScene = payScene;
    }

    public TradePlatformEnum getPayChannel() {
        return payChannel;
    }

    public void setPayChannel(TradePlatformEnum payChannel) {
        this.payChannel = payChannel;
    }

    public String getPayeeName() {
        return payeeName;
    }

    public void setPayeeName(String payeeName) {
        this.payeeName = payeeName;
    }

    public String getPayeeEmployeeNo() {
        return payeeEmployeeNo;
    }

    public void setPayeeEmployeeNo(String payeeEmployeeNo) {
        this.payeeEmployeeNo = payeeEmployeeNo;
    }

    public Long getPayeeId() {
        return payeeId;
    }

    public void setPayeeId(Long payeeId) {
        this.payeeId = payeeId;
    }

    public ExitingTypeEnum getExitingType() {
        return exitingType;
    }

    public void setExitingType(ExitingTypeEnum exitingType) {
        this.exitingType = exitingType;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    public Long getSyncDataTime() {
        return syncDataTime;
    }

    public void setSyncDataTime(Long syncDataTime) {
        this.syncDataTime = syncDataTime;
    }

    public String getCreateBy() {
        return createBy;
    }

    public void setCreateBy(String createBy) {
        this.createBy = createBy;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public String getUpdateBy() {
        return updateBy;
    }

    public void setUpdateBy(String updateBy) {
        this.updateBy = updateBy;
    }

    public Date getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }

    public Byte getDelFlag() {
        return delFlag;
    }

    public void setDelFlag(Byte delFlag) {
        this.delFlag = delFlag;
    }

    public List<ParkingPayOrder> getParkingPayOrders() {
        return parkingPayOrders;
    }

    public void setParkingPayOrders(List<ParkingPayOrder> parkingPayOrders) {
        this.parkingPayOrders = parkingPayOrders;
    }

    public String getLedShow() {
        return ledShow;
    }

    public void setLedShow(String ledShow) {
        this.ledShow = ledShow;
    }

    public static long getSerialVersionUID() {
        return serialVersionUID;
    }

    public void builderParkingLot(ParkingLotBaseInfo parkingLotBaseInfo) {
        if (parkingLotBaseInfo  == null) {
            return;
        }
        this.parkingLotId = parkingLotBaseInfo.getParkingLotId();
        this.parkingLotName = parkingLotBaseInfo.getParkingLotName();
        this.parentParkingLotId =parkingLotBaseInfo.getParkingLotId();
        this.parentParkingLotName = parkingLotBaseInfo.getParkingLotName();
        this.licenseRevise = StatusEnum.NO;
    }

    public void builder(ParkingLotBaseInfo parkingLotBaseInfo,ParkingLotDrivewayInfo parkingLotDrivewayInfo,ParkingDTO parkingDTO){
        parkingDTO.setParentParkingLotId(parkingLotBaseInfo.getParkingLotId());
        parkingDTO.setParkingLotId(parkingLotBaseInfo.getParkingLotId());
        builderParkingLot(parkingLotBaseInfo);
        builderDriveway(parkingLotDrivewayInfo,parkingDTO);
    }

    public void builderDriveway(ParkingLotDrivewayInfo parkingLotDrivewayInfo,ParkingDTO parkingDTO) {

        if (parkingLotDrivewayInfo  == null) {
            return;
        }

        if (parkingLotDrivewayInfo.getDrivewayType() == DrivewayTypeEnum.ENTRANCE) {
            this.entDrivewayId =parkingLotDrivewayInfo.getDrivewayId();
            this.entDrivewayName=parkingLotDrivewayInfo.getDrivewayName();
            builderParkingDTO(parkingDTO,parkingLotDrivewayInfo.getDrivewayType());
        }else {
            this.exitDrivewayId =parkingLotDrivewayInfo.getDrivewayId();
            this.exitDrivewayName=parkingLotDrivewayInfo.getDrivewayName();
            builderParkingDTO(parkingDTO,parkingLotDrivewayInfo.getDrivewayType());
        }
    }

    public void builderParkingDTO(ParkingDTO parkingDTO,DrivewayTypeEnum drivewayTypeEnum) {
        if (ObjectUtil.isNotEmpty(parkingDTO.getCarLicense())) {
            this.carLicense=parkingDTO.getCarLicense();
            this.licenseColor=parkingDTO.getLicenseColor();
        }
        this.carType = parkingDTO.getLicenseColor().getCarType();
        if (drivewayTypeEnum == DrivewayTypeEnum.ENTRANCE) {
            this.entCarImageUrl =parkingDTO.getCarImageUrl();
            this.entTime=parkingDTO.getCaptureTime();
        }else {
            this.exitCarImageUrl =parkingDTO.getCarImageUrl();
            this.exitTime=parkingDTO.getCaptureTime();
            if (this.entTime!=null&&this.exitTime!=null){
                this.parkingTime = DateUtil.formatBetween(this.entTime, this.exitTime, BetweenFormatter.Level.SECOND);
            }

        }
    }

    public void builderCarInfo(CarTypeInfoVO carTypeInfo) {
        this.parkingType = carTypeInfo.getParkingType();
        this.parkingCarType = carTypeInfo.getParkingCarType();
        this.carTypeId = carTypeInfo.getCarTypeId();
        this.carTypeName = carTypeInfo.getCarTypeName();
        if (carTypeName == null || "".equals(carTypeName)){
            this.carTypeName = carTypeInfo.getParkingType().getName();
        }
    }

    public void builderBilling(BillingResult billingResult) {
        this.amount = billingResult.getTotalAmount();
        this.payAmount = billingResult.getPayAmount();
        this.discountAmount = billingResult.getDiscountAmount();
        this.payStatus = billingResult.getPayStatus();
        this.payableAmount = billingResult.getPayableAmount();
        if (this.payAmount != null && this.payAmount.doubleValue()>0) {
            this.payableAmount = billingResult.getPayableAmount().subtract(this.payAmount);
            if (this.payableAmount.doubleValue() <= 0) {
                this.payableAmount = BigDecimal.ZERO;
                this.payStatus = PayStatusEnum.PAY_SUCCESS;
            }
        }
    }
}